package com.devops.admin.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.devops.admin.po.DOSK8sIngressRulesPo;
import com.devops.admin.po.DOSK8sIngressPo;
import com.devops.admin.po.DOSingressRulePo;
import com.devops.constant.DevOpsConstant;
import io.fabric8.kubernetes.api.model.networking.v1.*;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName K8sClientUtil
 * @Description TODO
 * @Author hepingguo
 * @Date 2022/5/20 08:41
 * @Version 1.0
 **/
@Slf4j
public class K8sClientUtil {

    public static KubernetesClient getKubernetesClient(String configPath, String configContent) {
        String configYAML = null;
        try {
            if (StrUtil.isNotBlank(configPath)) {
                StringBuffer path = new StringBuffer(DevOpsConstant.K8sConfig.CONFIG_PATH_PREFIX);
                File configFile = new File(path.append(configPath).toString());
                configYAML = String.join("\n", Files.readAllLines(configFile.toPath()));
            }else if (StrUtil.isNotBlank(configContent)){
                configYAML = configContent;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        Assert.isTrue(StrUtil.isNotBlank(configYAML),"config路径无效或内容填写不正确");
        System.setProperty("kubernetes.disable.autoConfig","true");
        Config config = Config.fromKubeconfig(configYAML);
        log.info("#####################################################"+config.getMasterUrl());
        return new DefaultKubernetesClient(config);
    }

    public static List<DOSK8sIngressPo> analysisIngress(IngressList ingressList, String clusterName, String ingressName){
        List<DOSK8sIngressPo> ingressPos = new ArrayList<>();
        for (Ingress ingress : ingressList.getItems()) {
            // 这里是为了按名字查询ingress，没有这样的需求可以不用传值
            DOSK8sIngressPo ingressPo = getDOSK8sIngressPo(clusterName, ingress);
            if (StrUtil.isBlank(ingressName) || (StrUtil.isNotBlank(ingressName) && ingress.getMetadata().getName().contains(ingressName))
                    || (StrUtil.isNotBlank(ingressName) && ingressPo.getRuleStr().contains(ingressName))){
                ingressPos.add(ingressPo);
            }
        }

        return ingressPos;
    }

    public static DOSK8sIngressPo getDOSK8sIngressPo(String clusterName, Ingress ingress) {
        if (ingress == null){
            return null;
        }
        DOSK8sIngressPo clusterPo = new DOSK8sIngressPo();
        clusterPo.setClusterName(clusterName);
        clusterPo.setIngressName(ingress.getMetadata().getName());
        clusterPo.setApiVersion(ingress.getApiVersion());
        clusterPo.setIngressNamespace(ingress.getMetadata().getNamespace());
        String createTime = ingress.getMetadata().getCreationTimestamp();
        clusterPo.setIngressCreateTIme(TimeUtil.getDate(createTime));
        // 获取annotation
        Map<String, String> annotations = ingress.getMetadata().getAnnotations();
        if (CollectionUtil.isNotEmpty(annotations)) {
            String[] str = new String[annotations.size()];
            int i = 0;
            for (Map.Entry<String, String> entry : annotations.entrySet()) {
                str[i] = entry.getKey() + "=" + entry.getValue();
                i++;
            }
            clusterPo.setAnnotations(str);
        }
        // 获取labels
        Map<String, String> labelsMap = ingress.getMetadata().getLabels();
        if (CollectionUtil.isNotEmpty(labelsMap)){
            String[] labels = new String[labelsMap.size()];
            int i = 0;
            for (Map.Entry<String, String> entry : labelsMap.entrySet()) {
                labels[i] = entry.getKey()+"="+entry.getValue();
                i++;
            }
            clusterPo.setLabels(labels);
        }

        // 查询端口号
//        if (ingress.getSpec().getBackend() != null && ingress.getSpec().getBackend().getServicePort() != null){
//            Integer ports = ingress.getSpec().getBackend().getServicePort().getIntVal();
//            clusterPo.setPorts(ports.toString());
//        }

        IngressSpec spec = ingress.getSpec();
        List<IngressRule> rules = spec.getRules();
        // 获取并拼接rules
        StringBuilder rulesStr = new StringBuilder();
        // 拼接ports
        StringBuilder ports = new StringBuilder();
        List<DOSingressRulePo> rulesPos = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(rules)){
            for (IngressRule ingressRule : rules) {
                DOSingressRulePo rulePo = new DOSingressRulePo();
                List<DOSK8sIngressRulesPo> ingressRulesPos = new ArrayList<>();
                String host = "";
                if (StrUtil.isNotBlank(ingressRule.getHost())){
                    if(clusterPo.getIngressName().contains("tls")
                            || clusterPo.getIngressName().contains("https")){
                        host = "https://"+ingressRule.getHost();
                    }else {
                        host = "http://"+ingressRule.getHost();
                    }

                    rulePo.setHost(ingressRule.getHost());
                }
                HTTPIngressRuleValue http = ingressRule.getHttp();
                if (http != null){
                    List<HTTPIngressPath> paths = http.getPaths();
                    if (CollectionUtil.isNotEmpty(paths)){
                        for (HTTPIngressPath httpIngressPath : paths) {
                            IngressBackend backend = httpIngressPath.getBackend();
                            if (backend != null && StrUtil.isNotBlank(backend.getService().getName())){
                                rulesStr.append(host)
                                        .append(StrUtil.isNotBlank(httpIngressPath.getPath()) ? httpIngressPath.getPath() : "")
                                        .append(" ⇢ ")
                                        .append(backend.getService().getName())
                                        .append(":")
                                        .append(backend.getService().getPort().getNumber())
                                        .append(";");
                                ports.append(backend.getService().getPort().getNumber()).append(",");
                                DOSK8sIngressRulesPo rulesPo = DOSK8sIngressRulesPo.builder()
                                        .path(StrUtil.isNotBlank(httpIngressPath.getPath()) ? httpIngressPath.getPath() : "")
                                        .link(host+"/")
                                        .backends(backend.getService().getName() + ":" + backend.getService().getPort().getNumber())
                                        .build();
                                ingressRulesPos.add(rulesPo);
                            }
                        }
                    }
                }
                rulePo.setRules(ingressRulesPos);
                rulesPos.add(rulePo);
            }
        }
        String[] split = rulesStr.toString().split(";");
        clusterPo.setRuleStr(rulesStr.toString());
        clusterPo.setRules(split);
        if (StrUtil.isNotBlank(ports.toString())) {
            clusterPo.setPorts(ports.substring(0,ports.length()-1));
        }
        clusterPo.setRulesList(rulesPos);
        return clusterPo;
    }

    public static String[] dealMapToStringArray(Map<String,String> map) {
        String[] array = null;
        if (CollectionUtil.isNotEmpty(map)) {
            array = map.toString()
                    .replace("{","").replace("}","")
                    .split(",");
        }
        return array;
    }
}
